package leetcode.editor.cn.dsa21_heapAndTrie;
//给定一个字符串，请将字符串里的字符按照出现的频率降序排列。
//
// 示例 1: 
//输入:
//"tree"
//输出:
//"eert"
//
//解释:
//'e'出现两次，'r'和't'都只出现一次。
//因此'e'必须出现在'r'和't'之前。此外，"eetr"也是一个有效的答案。
//
// 示例 2: 
//输入:
//"cccaaa"
//输出:
//"cccaaa"
//
//解释:
//'c'和'a'都出现三次。此外，"aaaccc"也是有效的答案。
//注意"cacaca"是不正确的，因为相同的字母必须放在一起。
//
// 示例 3: 
//输入:
//"Aabb"
//输出:
//"bbAa"
//
//解释:
//此外，"bbaA"也是一个有效的答案，但"Aabb"是不正确的。
//注意'A'和'a'被认为是两种不同的字符。
// 
// Related Topics 堆 哈希表 
// 👍 197 👎 0

import java.util.PriorityQueue;

public class SortCharactersByFrequency451 {
    //leetcode submit region begin(Prohibit modification and deletion)
    class Solution {
        public String frequencySort(String s) {
            // 定义哈希表，存储每个字符出现的频次
            int[] charsFrequen = new int[128];
            for (int i = 0; i < s.length(); i++) {
                charsFrequen[s.charAt(i) + 0]++;
            }
            // 定义最大堆，存储每一个字符，根据字符出现的频次排序
            PriorityQueue<Character> queue = new PriorityQueue<>((o1, o2) -> {
                return charsFrequen[o2 + 0] - charsFrequen[o1 + 0];
            });
            for (int i = 0; i < 128; i++) {
                if (charsFrequen[i] != 0) {
                    queue.offer((char)i);
                }
            }
            StringBuilder sb = new StringBuilder();
            // 让队列依次出队，拼接上对应频次的字符
            while (!queue.isEmpty()) {
                char c = queue.poll();
                for (int i = 0; i < charsFrequen[c + 0]; i++) {
                    sb.append(c);
                }
            }
            return sb.toString();
        }
    }
    //leetcode submit region end(Prohibit modification and deletion)
}